import { Injectable, ExecutionContext, UnauthorizedException } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { AuthGuard } from '@nestjs/passport';
import {
  Constant_Enum_Enum_UserClient_Status,
  Constant_Enum_Enum_UserAdmin_Status,
} from '../constants/enum';
import { constant_Index_IsPublic } from '../constants';
import { IJwtStrategyPayload } from '../typeScripts';

/**
 * @description 自定义 JWT 认证守卫类，用于处理 JWT 认证和用户权限校验。
 * @extends {AuthGuard('jwt')}
 */
@Injectable()
export class Guard_JwtAuth_Base extends AuthGuard('jwt') {
  constructor(private reflector: Reflector) {
    super();
  }

  /**
   * 重写 canActivate 方法，判断当前路由是否为公开路由。
   * @param {ExecutionContext} context - 执行上下文。
   * @returns {any} - 如果是公开路由，返回 true，否则调用父类的 canActivate 方法。
   */
  canActivate(context: ExecutionContext): any {
    const isPublic = this.reflector.getAllAndOverride<boolean>(constant_Index_IsPublic, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (isPublic) {
      return true;
    }
    return super.canActivate(context);
  }

  /**
   * 重写 handleRequest 方法，处理 JWT 认证后的用户信息校验。
   * @param {any} err - 认证过程中产生的错误。
   * @param {any} user - 经过认证的用户信息。
   * @returns {any} - 返回认证后的用户信息，如果认证失败，抛出 UnauthorizedException。
   */
  handleRequest(err: any, user: any): any {
    const userCopy = user as IJwtStrategyPayload;
    if (
      err ||
      !user ||
      ((userCopy.type == 'web' || userCopy.type == 'webWx') &&
        userCopy.statusUser === Constant_Enum_Enum_UserClient_Status.UserClient_Status_Disable) ||
      (userCopy.type == 'adm' &&
        userCopy.statusUser === Constant_Enum_Enum_UserAdmin_Status.UserAdmin_Status_Disable)
    ) {
      throw err || new UnauthorizedException();
    }
    return user;
  }
}
